using System;
using System.Collections.Generic;
using System.Text;

namespace RapidHDL
{
    public class TestPipelineSerializer : RapidHardware
    {
        PipelineSerializer oSerializer;
        PipelineBuffer oBuffer;

        public override bool ConfigureSettings()
        {
            Settings.UseStart = false;
            Settings.BuildHardware = true;
            Settings.ForceBuildHardware = false;
            Settings.RunFromXilinx = true;
            Settings.ClockFrequency = 10;
            Settings.UseSDRAM = true;
            Settings.BuildRemote = false;
            return true;
        }

        public override bool GenerateStructure(TopLevelComponent TopLevelComponent)
        {
            TopLevelComponent.TestBusWrite.Join(0);

            oSerializer = new PipelineSerializer(TopLevelComponent, "serializer", TopLevelComponent.MainClock, TopLevelComponent.MainReset,6,2);
            oBuffer = new PipelineBuffer(TopLevelComponent, "buffer", TopLevelComponent.MainClock, TopLevelComponent.MainReset, 6, 4);

            oSerializer.InputBus.Join(oBuffer.OutputBus);

            SystemInterface.AddSignalSource("data_i", oBuffer.InputBus.Data, 0);
            SystemInterface.AddSignalSource("data_ready_i", oBuffer.InputBus.DataReady, 0);
            SystemInterface.AddSignalSource("stall_i", oSerializer.OutputBus.Stall, 0);

            return true;
        }

        public override bool ConfigureSignalViews(TopLevelComponent TopLevelComponent)
        {
            //SystemInterface.FormatSignalView("pipe0_o", SignalFormat.Unsigned);

            SystemInterface.AddSignalView("data_o", oSerializer.OutputBus.Data);
            SystemInterface.AddSignalView("data_ready_o", oSerializer.OutputBus.DataReady);
            SystemInterface.AddSignalView("stall_o", oSerializer.InputBus.Stall);

            SystemInterface.AddSignalView("state_0", oSerializer.oStateMachine.StateCurrent("state_0"));
            SystemInterface.AddSignalView("state_1", oSerializer.oStateMachine.StateCurrent("state_1"));
            SystemInterface.AddSignalView("state_2", oSerializer.oStateMachine.StateCurrent("state_2"));
            SystemInterface.AddSignalView("state_reset", oSerializer.oStateMachine.StateCurrent("state_reset"));
            SystemInterface.AddSignalView("data_in", oSerializer.InputBus.Data);
            SystemInterface.AddSignalView("data_ready_in", oSerializer.InputBus.DataReady);
            SystemInterface.AddSignalView("data_staged", oSerializer.oInputStage.OutputBus.Data);
            return true;
        }



        private void ViewOutputs(HardwareScript poScript, int piTime)
        {
            poScript.Echo(piTime, "======================================== Time : " + piTime.ToString());
            poScript.SignalView(piTime, "data_o");
            poScript.SignalView(piTime, "data_ready_o");
            poScript.SignalView(piTime, "stall_o");
            //poScript.Echo(piTime, "-----");
            poScript.SignalView(piTime, "state_reset");
            poScript.SignalView(piTime, "state_0");
            poScript.SignalView(piTime, "state_1");
            poScript.SignalView(piTime, "state_2");
            poScript.SignalView(piTime, "data_in");
            poScript.SignalView(piTime, "data_ready_in");
            poScript.SignalView(piTime, "data_staged");
            poScript.Echo(piTime, "=====***********************************");
        }

        private void SetInputs(HardwareScript poScript, int piTime, int piData, int piDataReady, int piStall)
        {
            poScript.SignalOut(piTime, "data_i", piData.ToString(), SignalFormat.Unsigned);
            poScript.SignalOut(piTime, "data_ready_i", piDataReady.ToString());
            poScript.SignalOut(piTime, "stall_i", piStall.ToString());
        }


        public override bool GenerateHardwareScripts()
        {
            HardwareScript oScript = HardwareScripts.NewScript("test");
            oScript.NoReset = false;

            SetInputs(oScript, 2, 3, 1, 0);
            SetInputs(oScript, 3, 9, 1, 0);
            SetInputs(oScript, 4, 27, 1, 0);
            SetInputs(oScript, 5, 34, 1, 0);
            SetInputs(oScript, 6, 0, 0, 0);
            SetInputs(oScript, 21, 12, 1, 0);
            SetInputs(oScript, 22, 15, 0, 0);

            SetInputs(oScript, 30, 15, 0, 1);
            SetInputs(oScript, 31, 12, 1, 1);
            SetInputs(oScript, 32, 12, 0, 1);
            SetInputs(oScript, 33, 15, 1, 1);
            SetInputs(oScript, 34, 15, 0, 1);
            SetInputs(oScript, 35, 15, 0, 0);

            for (int iTime = 29; iTime < 41; iTime++)
                ViewOutputs(oScript,iTime);

            return true;
        }

    }
}

